﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CommonsLib.Utility
{
    public class BaseFunctions
    {
        public static string GetFilePath(Type type)
        {
            string strPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetAssembly(type).CodeBase);
            if (strPath.StartsWith(@"file:\"))
            {
                strPath = strPath.Substring(@"file:\".Length);
            }
            return strPath;
        }

        public static object CreateGeneric(Type generic, Type innerType, params object[] args)
        {

            System.Type specificType = generic.MakeGenericType(new System.Type[] { innerType });
            return Activator.CreateInstance(specificType, args);

        }

        #region Format
        public static string FormatDate(string dt)
        {
            string strFormatDate = string.Empty;

            if (dt != string.Empty && dt.Trim() != "/  /")
                strFormatDate = DateTime.Parse(dt).ToString("MM/dd/yyyy");

            return strFormatDate;
        }

        public static string FormatNumeric(object dblData, string strFormatStyle)
        {
            if (dblData == null) dblData = string.Empty;
            return FormatNumeric(dblData.ToString(), strFormatStyle);
        }
        public static string FormatNumeric(string strData, string strFormatStyle)
        {
            int intDigitPos = 0;
            bool blnTrimEndZeroChar = false;
            string strValue1 = string.Empty, strValue2 = string.Empty;

            if (strFormatStyle.ToUpper().Trim() == "N.?")
            {
                blnTrimEndZeroChar = true;
                strFormatStyle = "N.N";
            }

            if (strFormatStyle.ToUpper().Trim() == "NS.?")
            {
                blnTrimEndZeroChar = true;
                strFormatStyle = "NS.N";
            }

            strData = strData.Replace(",", "").Trim();

            //Format the strData to NumerricType
            if (!BaseFunctions.IsNumeric(strData))
            {
                strData = "0";
            }
            else
            {
                if (strData.Substring(0, 1) == ".")
                    strData = "0" + strData;
                if (strData.Substring(strData.Length - 1, 1) == ".")
                    strData = strData.Substring(0, strData.Length - 1);
            }
            switch (strFormatStyle.ToUpper())
            {
                case "NN"://no format , remove "," in strField_Char  and remove left "0"
                    strData = strData.Replace(",", "");
                    while (strData.Substring(0, 1) == "0" && strData.Length > 1 && strData.Substring(1, 1) != ".")
                    {
                        strData = strData.Substring(1, strData.Length - 1);
                    }
                    return (strData);
                case "N.N"://no format , remove "," in strField_Char  and remove left "0"
                    strData = strData.Replace(",", "");
                    while (strData.Substring(0, 1) == "0" && strData.Length > 1 && strData.Substring(1, 1) != ".")
                    {
                        strData = strData.Substring(1, strData.Length - 1);
                    }
                    if (blnTrimEndZeroChar)
                    {
                        while (strData.IndexOf(".") >= 0 && strData.Length > 0 && strData.Substring(strData.Length - 1, 1) == "0")
                        {
                            strData = strData.Substring(0, strData.Length - 1);
                        }
                        if (strData.Length > 0 && strData.Substring(strData.Length - 1, 1) == ".") strData = strData.Substring(0, strData.Length - 1);
                    }
                    if (strData.Trim() == string.Empty) strData = "0";
                    return (strData);
                case "NS.N"://'number do not format ,but need add number separator ","
                    strData = strData.Replace(",", "");

                    intDigitPos = strData.IndexOf(".", 0);//get the position of radix point
                    if (intDigitPos > 0)
                    {
                        strValue1 = FormatSeparatorNumeric(strData.Substring(0, intDigitPos));
                        strValue2 = strData.Substring(intDigitPos + 1, strData.Length - intDigitPos - 1);
                        strData = strValue1 + "." + strValue2;
                    }
                    else
                        strData = FormatSeparatorNumeric(strData);
                    if (blnTrimEndZeroChar)
                    {
                        while (strData.IndexOf(".") >= 0 && strData.Length > 0 && strData.Substring(strData.Length - 1, 1) == "0")
                        {
                            strData = strData.Substring(0, strData.Length - 1);
                        }
                        if (strData.Length > 0 && strData.Substring(strData.Length - 1, 1) == ".") strData = strData.Substring(0, strData.Length - 1);
                    }
                    if (strData.Trim() == string.Empty) strData = "0";
                    return (strData);
                case "NS"://'number do not format ,but need add number separator ","
                    strData = strData.Replace(",", "");

                    intDigitPos = strData.IndexOf(".", 0);//get the position of radix point
                    if (intDigitPos > 0)
                    {
                        strValue1 = FormatSeparatorNumeric(strData.Substring(0, intDigitPos));
                        strValue2 = strData.Substring(intDigitPos + 1, strData.Length - intDigitPos - 1);
                        strData = strValue1 + "." + strValue2;
                    }
                    else
                        strData = FormatSeparatorNumeric(strData);
                    return (strData);
                default:
                    if (strFormatStyle.IndexOf(".") >= 0 && BaseFunctions.IsNumeric(strFormatStyle.Substring(strFormatStyle.IndexOf(".") + 1)))
                    {

                        strData = Round(strData, Int32.Parse(strFormatStyle.Substring(strFormatStyle.IndexOf(".") + 1)));

                        //strData = decimal.Round(decimal.Parse(strData, System.Globalization.NumberStyles.AllowDecimalPoint | System.Globalization.NumberStyles.AllowLeadingSign), Int32.Parse(strFormatStyle.Substring(strFormatStyle.IndexOf(".") + 1)), MidpointRounding.ToEven  ).ToString();

                    }
                    break;
            }

            strFormatStyle = strFormatStyle.Substring(1, strFormatStyle.Length - 1).ToUpper();

            string strChar = string.Empty;
            if (strFormatStyle != string.Empty)
                strChar = strFormatStyle.Substring(0, 1);

            bool bSp = false;

            if (strChar == "S")
            {
                bSp = true;
                strFormatStyle = strFormatStyle.Substring(1, strFormatStyle.Length - 1);
            }
            else if ((strChar == ".") || (strChar == string.Empty) || (Char.IsNumber(strChar, 0)))
            {
                bSp = false;
            }
            else if (((char.Parse(strChar)) >= 'A' && (char.Parse(strChar)) <= 'R') || ((char.Parse(strChar)) >= 'T' && (char.Parse(strChar)) <= 'Z'))
            {
                bSp = false;
                strFormatStyle = strFormatStyle.Substring(1, strFormatStyle.Length - 1);
            }
            else
            {
                return (strData);
            }

            int intWidth = 0;
            int intScaleWidth = 0;
            // string strAddChar = string.Empty;
            int intForLen = 0;

            intDigitPos = strFormatStyle.IndexOf(".");

            if (intDigitPos < 0) //"N" , "NS"
            {
                if (strFormatStyle == string.Empty)
                    intWidth = 0;
                else
                    intWidth = Int32.Parse(strFormatStyle);
                intScaleWidth = 0;
            }
            else if (intDigitPos == 0) //"N.2" ,"NS.2"
            {
                intWidth = 0;
                intScaleWidth = Int32.Parse(strFormatStyle.Substring(1, strFormatStyle.Length - 1));
            }
            else if (intDigitPos >= 1) //"NS10.2" , "NS10.2B" , "NS10.2Z"
            {
                intWidth = Int32.Parse(strFormatStyle.Substring(0, intDigitPos));
                intScaleWidth = Int32.Parse(strFormatStyle.Substring(intDigitPos + 1));
            }


            //Add scale
            if (intScaleWidth > 0)
            {
                intDigitPos = strData.IndexOf(".");
                if (intDigitPos >= 0)
                {
                    strValue2 = strData.Substring(intDigitPos + 1, strData.Length - intDigitPos - 1);
                }
                else
                {
                    strData = strData + ".";
                    strValue2 = string.Empty;
                }
                intForLen = intScaleWidth - strValue2.Length;
                if (intForLen > 0)
                {
                    for (int i = 0; i < intForLen; i++)
                    {
                        strData += "0";
                    }
                }

            }

            //Add spearater
            if (bSp)
            {
                strData = strData.Replace(",", "");
                intDigitPos = strData.IndexOf(".");
                if (intDigitPos >= 0)
                {
                    strValue1 = FormatSeparatorNumeric(strData.Substring(0, intDigitPos));
                    strValue2 = strData.Substring(intDigitPos + 1, strData.Length - intDigitPos - 1);
                    strData = strValue1 + "." + strValue2;

                }
                else
                {
                    strData = FormatSeparatorNumeric(strData);
                }
            }

            return strData;

        }

        private static string FormatSeparatorNumeric(string strData)
        {
            string StrTemp = string.Empty, strSign = string.Empty;
            int iIndex = 0;

            if (strData.Length > 0 && strData.Substring(0, 1) == "-")
            {
                strSign = "-";
                strData = strData.Substring(1);

            }
            int intLen = strData.Length;
            for (int i = intLen - 1; i >= 0; i--)
            {
                iIndex++;
                StrTemp = strData.Substring(i, 1) + StrTemp;
                if (iIndex % 3 == 0)
                    StrTemp = "," + StrTemp;
            }

            if (StrTemp != string.Empty && StrTemp[0] == ',')
            {
                StrTemp = StrTemp.Substring(1, StrTemp.Length - 1);
            }
            return (strSign + StrTemp);
        }

        private static int GetIntFromStr(string strData)
        {
            string strTemp = string.Empty;
            int intNum = 0;
            int intLen = strData.Length;
            for (int i = 0; i < intLen; i++)
            {
                if (Char.IsNumber(strData[i]))
                {
                    strTemp += strData.Substring(i, 1);
                }
            }

            if (strTemp != string.Empty)
            {
                intNum = int.Parse(strTemp);
            }
            return (intNum);
        }

        public static string Round(string strdata, int iDecimal)
        {
            strdata = strdata.Replace(",", "").Trim();
            int iPointLocate = strdata.IndexOf('.');
            bool bIsNegative = (strdata.IndexOf('-') != -1);
            if (iPointLocate <= 0) return strdata;

            int iDecimalScale = strdata.Length - iPointLocate - 1;
            if (iDecimalScale <= iDecimal) return strdata;
            int iDigit = int.Parse(strdata.Substring(iPointLocate + iDecimal + 1, 1));
            if (iDigit >= 5)
            {
                if (bIsNegative)
                    strdata = Convert.ToString(double.Parse(strdata.Substring(0, iPointLocate + iDecimal + 1)) - 1 / Math.Pow(10, iDecimal));
                else
                    strdata = Convert.ToString(double.Parse(strdata.Substring(0, iPointLocate + iDecimal + 1)) + 1 / Math.Pow(10, iDecimal));
            }
            else
            {
                strdata = Convert.ToString(double.Parse(strdata.Substring(0, iPointLocate + iDecimal + 1)));
            }
            return strdata;
        }

        public static bool IsNumeric(string Value)
        {
            return IsNumeric(Value, false);
        }

        public static bool IsNumeric(string Value, bool bIncludeSpecString)
        {
            if (bIncludeSpecString)
            {
                Value = Value.Replace("$", "").Replace("(", "").Replace(")", "").Trim();
            }

            string strValue = CvtFunc.ToString(Value);

            int iLength = strValue.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Length;

            if (strValue == null || strValue == string.Empty || iLength == 0 || iLength > 2)
            {
                return false;
            }
            else
            {
                strValue = strValue.Replace(",", "");

                if (strValue.Substring(0, 1) == "-")
                {
                    strValue = strValue.Substring(1, strValue.Length - 1);
                    if (strValue == string.Empty) return false;
                }

                foreach (char c in strValue.ToCharArray())
                {
                    if (!(char.IsNumber(c) || c == '.'))
                    {
                        return false;
                    }
                }

                if (strValue.IndexOf("..") > 0) return false;
                return true;
            }

        }
        #endregion
    }
}
